package cn.edu.sdyu.ie.crs.api;

import cn.edu.sdyu.ie.crs.common.response.NamedValue;
import cn.edu.sdyu.ie.crs.common.response.PageVO;
import cn.edu.sdyu.ie.crs.common.response.Result;
import cn.edu.sdyu.ie.crs.domain.Device;
import cn.edu.sdyu.ie.crs.domain.DeviceRunLog;
import cn.edu.sdyu.ie.crs.iot.HaDeviceState;
import cn.edu.sdyu.ie.crs.iot.HomeAssistantService;
import cn.edu.sdyu.ie.crs.service.DeviceRunLogService;
import cn.edu.sdyu.ie.crs.service.DeviceService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

@Tag(name = "设备管理", description = "设备信息管理接口")
@Slf4j
@RestController
@RequestMapping("api/device")
public class DeviceController {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private HomeAssistantService homeAssistantService;
    @Autowired
    private DeviceRunLogService deviceRunLogService;

    /**
     * 添加新设备信息
     * @param device 设备信息
     * @return
     */
    @Operation(tags = "设备管理", summary = "添加设备信息")
    @PostMapping("")
    public Result<Void> addDevice(Device device) {

        if(device.getId() != null && !device.getId().equals(0)) {
            log.warn("请求ID参数，若更新对象，请使用PUT方式发起请求。");
            return Result.failure();
        }
        deviceService.saveDevice(device);
        return Result.success();
    }

    /**
     * 更新设备信息
     * @param device 设备信息
     * @return
     */
    @Operation(tags = "设备管理", summary = "修改设备信息")
    @PutMapping("")
    public Result<Void> updateDevice(Device device) {

        if(device.getId() == null || device.getId().equals(0)) {
            log.warn("未请求ID参数，使用POST方式创建对象。当前不会更新任何对象");
            return Result.failure();
        }
        deviceService.saveDevice(device);
        return Result.success();
    }

    /**
     * 删除指定ID的设备信息
     * @param id 设备ID
     * @return
     */
    @Operation(tags = "设备管理", summary = "删除设备信息")
    @DeleteMapping("/{id}")
    public Result<Void> deleteDeviceById(@PathVariable Integer id) {
        deviceService.deleteDeviceById(id);
        return Result.success();
    }

    /**
     * 查询指定ID的设备信息
     * @param id 设备ID
     * @return
     */
    @Operation(tags = "设备管理", summary = "查询指定ID的设备信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "设备ID")
    })
    @GetMapping("/{id}")
    public Result<Device> findDeviceById(@PathVariable Integer id) {
        Device device = deviceService.findDeviceById(id);

        if(device == null) {
            return Result.failure();
        }

        return Result.success(device);
    }

    /**
     * 分页查询设备信息
     * @param page 页码
     * @param pageSize 分页大小
     * @return 分页设备信息
     */
    @Operation(tags = "设备管理", summary = "分页查询设备信息")
    @GetMapping("")
    public Result<PageVO<Device>> listDevicesPage(@RequestParam(defaultValue = "1") Integer page,
                                                        @RequestParam(defaultValue = "10") Integer pageSize) {

        Page<Device> list = deviceService.findByPage(page - 1, pageSize);
        PageVO<Device> pageVO = PageVO.getPageVO(list);
        return Result.success(pageVO);
    }

    /**
     * 查询指定设备的状态
     * @param id 设备ID
     * @return 设备状态
     */
    @Operation(tags = "设备管理", summary = "查询指定设备的状态")
    @GetMapping("/{id}/state")
    public Result<HaDeviceState> getDeviceStateById(@PathVariable Integer id) {
        Device device = deviceService.findDeviceById(id);
        HaDeviceState haDeviceState = homeAssistantService.getState(device);

        DeviceRunLog deviceRunLog = new DeviceRunLog();
        deviceRunLog.setDeviceName(device.getDeviceName());
        deviceRunLog.setDeviceCode(device.getDeviceCode());
        deviceRunLog.setDeviceType(device.getDeviceType());
        deviceRunLog.setLogType(1);
        deviceRunLog.setOperationType(1);
        deviceRunLog.setEvent(device.getDeviceCode() + ": 查询状态");
        deviceRunLog.setTime(new Date());
        deviceRunLog.setCreateTime(new Date());
        deviceRunLogService.saveDeviceRunLog(deviceRunLog);
        return Result.success(haDeviceState);
    }

    /**
     * 开启指定设备
     * @param id 设备ID
     * @return
     */
    @Operation(tags = "设备管理", summary = "开启指定设备")
    @PostMapping("/{id}/turnOn")
    public Result<Void> turnOnDeviceById(@PathVariable Integer id) {
        Device device = deviceService.findDeviceById(id);
        homeAssistantService.turnOn(device);
        device.setRuntimeStatus(1);
        deviceService.saveDevice(device);

        DeviceRunLog deviceRunLog = new DeviceRunLog();
        deviceRunLog.setDeviceName(device.getDeviceName());
        deviceRunLog.setDeviceCode(device.getDeviceCode());
        deviceRunLog.setDeviceType(device.getDeviceType());
        deviceRunLog.setLogType(1);
        deviceRunLog.setOperationType(1);
        deviceRunLog.setDeviceState(1);
        deviceRunLog.setEvent(device.getDeviceCode() + ": 设备开启");
        deviceRunLog.setTime(new Date());
        deviceRunLog.setCreateTime(new Date());
        deviceRunLogService.saveDeviceRunLog(deviceRunLog);
        return Result.success();
    }

    /**
     * 关闭指定设备
     * @param id 设备ID
     * @return
     */
    @Operation(tags = "设备管理", summary = "关闭指定设备")
    @PostMapping("/{id}/turnOff")
    public Result<Void> turnOffDeviceById(@PathVariable Integer id) {
        Device device = deviceService.findDeviceById(id);
        homeAssistantService.turnOff(device);
        device.setRuntimeStatus(0);
        deviceService.saveDevice(device);

        DeviceRunLog deviceRunLog = new DeviceRunLog();
        deviceRunLog.setDeviceName(device.getDeviceName());
        deviceRunLog.setDeviceCode(device.getDeviceCode());
        deviceRunLog.setDeviceType(device.getDeviceType());
        deviceRunLog.setLogType(1);
        deviceRunLog.setOperationType(1);
        deviceRunLog.setDeviceState(0);
        deviceRunLog.setEvent(device.getDeviceCode() + ": 设备关闭");
        deviceRunLog.setTime(new Date());
        deviceRunLog.setCreateTime(new Date());
        deviceRunLogService.saveDeviceRunLog(deviceRunLog);
        return Result.success();
    }

    /**
     * 统计总教室数
     */
    @Operation(tags = "设备管理", summary = "统计总设备数")
    @GetMapping("count/all")
    public Result<Long> countDevice() {
        Long count = deviceService.countDevice();
        return Result.success(count);
    }

    /**
     * 根据使用状态统计教室数
     * @param runtimeStatus
     * @return
     */
    @Operation(tags = "设备管理", summary = "根据使用状态统计设备数")
    @GetMapping("count/runtimeStatus")
    public Result<Long> countDeviceByRuntimeStatus(@RequestParam Integer runtimeStatus) {
        Long count = deviceService.countDeviceByRuntimeStatus(runtimeStatus);
        return Result.success(count);
    }

    /**
     * 按照使用模式分组统计教室数
     * @return
     */
    @Operation(tags = "设备管理", summary = "按照设备类型分组统计设备数")
    @GetMapping("count/groupByDeviceType")
    public Result<List<NamedValue>> countGroupByDeviceType() {
        List<NamedValue> count = deviceService.countGroupByDeviceType();
        return Result.success(count);
    }

    /**
     * 根据教室ID查询设备列表
     * @param classroomId
     * @return
     */
    @Operation(tags = "设备管理", summary = "根据教室ID查询设备列表")
    @GetMapping("classroom")
    public Result<List<Device>> getDevicesByClassroomId(@RequestParam Integer classroomId) {
        List<Device> devices = deviceService.findDevicesByClassroomId(classroomId);
        return Result.success(devices);
    }
}
